package org.kernely.security.dao;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
import org.kernely.persistence.service.SessionService;
import org.kernely.security.persistence.User;
import org.kernely.security.persistence.UserDetails;
import org.osgi.service.component.ComponentContext;

/**
 * Provides methods about UserDetails management
 */
public class UserDetailsDAO {
	/**
	 * SessionService service
	 */
	private static SessionService service;
	
	/**
	 * The user details dao instance
	 */
	private static UserDetailsDAO instance;
	
	/**
	 * Store the user details dao instance 
	 * @return the user details dao
	 */
	public static UserDetailsDAO getInstance() {
		return instance;
	}
	/**
	 * Set the persistence session service
	 * @param sessionService the session service to set
	 */
	public final void setPersistenceService(SessionService sessionService) {
		service = sessionService;
	}

	/**
	 * Activate the component
	 * @param ctxt the activation context
	 */
	protected final void activate(ComponentContext ctxt) {
		instance = this;
	}

	
	/**
	 * Retrieve UserDetails about the User u 
	 * @param u : the user specified
	 * @return the UserDetails about User u
	 */
	public final UserDetails getUserDetails(User u){
		Session session = service.getSession();
		Criteria crit = session.createCriteria(UserDetails.class);
		crit.add(Restrictions.like("user", u));
		List result = crit.list();
		if (result == null || result.size() <= 0){
			return null;
		}
		return (UserDetails) result.get(0);
	}
	
	/**
	 * Retrieve the specific user details
	 * @param detailId : the id of the user details
	 * @return
	 */
	public final UserDetails findUserDetails(int detailId){
		Session session = service.getSession();
		Criteria crit = session.createCriteria(UserDetails.class);
		crit.add(Restrictions.like("id_user_detail", detailId));
		return (UserDetails)crit.list().get(0);
	}
	
	/**
	 * Retrieve UserDetails about User with the ID id
	 * @param userId : the user's id needed
	 * @return the UserDetails about the user
	 */
	public final UserDetails getUserDetails(int userId){
		Session session = service.getSession();
		Criteria crit = session.createCriteria(UserDetails.class);
		crit.add(Restrictions.like("user", userId));
		return (UserDetails)crit.list().get(0);
	}
	
	/**
	 * Save UserDetails
	 * @param userDetails : the UserDetails to save
	 */
	public final void saveUserDetails(UserDetails userDetails){
		Session session = service.getSession();
		session.save(userDetails);
	}

	/**
	 * Update UserDetails
	 * @param userDetails : the UserDetails to update
	 */
	public final void updateUserDetails(UserDetails userDetails){
		Session session = service.getSession();
		session.merge(userDetails);
	}
	
	/**
	 * Gets the session service.
	 * @return the session service.
	 */
	public static SessionService getService() {
		return service;
	}

	/**
	 * Sets the session service.
	 * @param service the session service to set.
	 */
	public static void setService(SessionService service) {
		UserDetailsDAO.service = service;
	}
	
	/**
	 * Return all UserDetails stored into database
	 * @return the list of all UserDetails
	 */
	public final List<UserDetails> getAllUserDetails(){
		Session session = service.getSession();
		Criteria crit = session.createCriteria(UserDetails.class);
		return crit.list();
	}
	
	/**
	 * Search user details containing a specific text in name, firstname and mail.
	 * @param search The specific text to search.
	 * @return a set of UserDetails.
	 */
	public final Set<UserDetails> getSearchUserDetails(String search){
		Session session = service.getSession();
		String req = "SELECT * FROM kernely_user_details WHERE"
			+ " name like '%"+search+"%'"
			+ " OR mail like '%"+search+"%'"
			+ " OR firstname like '%"+search+"%';";
		Query query = session.createSQLQuery(req).addEntity(UserDetails.class);;

		return new HashSet<UserDetails>(query.list());
	}

	
}
